﻿using DocumentFormat.OpenXml.EMMA;
using MediatR;
using ProduceBasicData.Api.Application.Command.ProductionManage.Repost;
using ProduceBasicData.Api.Services;
using ProduceBasicData.Domain.FactoryModeling;
using ProduceBasicData.Domain.Material;
using ProduceBasicData.Domain.ProductionManage;
using ProduceBasicData.ErrorCode;
using ProduceBasicData.Infrastructure.Interface;

namespace ProduceBasicData.Api.Application.Handler.ProductionManage.Repost
{
    public class CreateReportCommandHandler : IRequestHandler<CreateReportCommand, ApiResult<int>>
    {
        private readonly IBaseRespository<Work_order> _work_order;
        private readonly IBaseRespository<Production_report> _production_report;
        private readonly IBaseRespository<ProductionModel> _productionRespository;
        private readonly IBaseRespository<ProductMaterialModel> _materiaRespository;
        private readonly IBaseRespository<Report_Record> _report_record;
        private readonly IBaseRespository<Report_approval> _report_approval;
        private readonly INotificationService _notificationService;
        private readonly ILogger<CreateReportCommandHandler> _logger;
        private readonly ICodeRuleService codeRuleService; // 新增

        public CreateReportCommandHandler(IBaseRespository<Work_order> work_order,
            IBaseRespository<Production_report> production_report,
            IBaseRespository<ProductionModel> productionRespository,
            IBaseRespository<ProductMaterialModel> materiaRespository,
            IBaseRespository<Report_Record> report_record,
            IBaseRespository<Report_approval> report_approval,
            INotificationService notificationService,
            ILogger<CreateReportCommandHandler> logger,
            ICodeRuleService codeRuleService)
        {
            _work_order = work_order;
            _production_report = production_report;
            _productionRespository = productionRespository;
            _materiaRespository = materiaRespository;
            _report_record = report_record;
            _report_approval = report_approval;
            _notificationService = notificationService;
            _logger = logger;
            this.codeRuleService = codeRuleService;
        }

        public async Task<ApiResult<int>> Handle(CreateReportCommand request, CancellationToken cancellationToken)
        {
            var result = new ApiResult<int>()
            {
                Code = ApiEnum.Success,
                Msg = "下发报工成功"
            };

            try
            {
                DateTime time = DateTime.Now;
                using (var transaction = await _production_report.DB.Database.BeginTransactionAsync(cancellationToken))
                {
                    // 获取工单信息
                    var order = await _work_order.GetModelAsync(request.Order_id);
                    if (order == null)
                    {
                        result.Code = ApiEnum.Failed;
                        result.Msg = "工单不存在";
                        return result;
                    }
                    // 1. 修改工单状态为2（待审核）000
                    order.Status = 2;
                    await _work_order.Update(order);


                    // 2. 创建报工记录（Production_report）
                    Production_report? productionReport = new Production_report
                    {

                        //Report_no = "BG"+(info.Count()+1).ToString().PadLeft(5,'0'),
                        Order_id = request.Order_id,
                        Process_id = request.Process_id,
                        Production_time = time, // 报工日期为当前时间
                        Product_id = request.Product_id,
                        Report_status = 1, // 1已提交
                        Plan_qty = order.Order_number, // 计划生产数量从工单获取
                        StartTime = order.Start_time,
                        EndTime = order.End_time,
                        CreateName = request.CreateName,
                        CreateTime = time
                    };

                    // 新增：自动生成 //报工编码
                    if (string.IsNullOrEmpty(productionReport.Report_no))
                    {
                        var generatedCode = await codeRuleService.AutoGenerateCodeAsync("ProduceBasicData.Domain.ProductionManage.Production_report");
                        if (!string.IsNullOrEmpty(generatedCode))
                        {
                            productionReport.Report_no = generatedCode;
                        }
                        else
                        {
                            // 如果没有配置规则，使用默认生成方式
                            productionReport.Report_no = $"WO{DateTime.Now:yyyyMMddHHmmss}";
                        }
                    }
                    await _production_report.AddAsync(productionReport);

                    // 3. 创建报工记录（Report_Record）
                    var reportRecord = new Report_Record
                    {
                        Report_no = productionReport.Report_no,
                        Task_id = productionReport.Id, // 关联报工ID
                        Product_id = request.Product_id,
                        Report_qty = order.Order_number, // 报工数量
                        ReportTime = time, // 报工提交时间
                        Operator_name = request.CreateName, // 这里可以从当前用户获取
                        Report_Status = 1, // 1待审核
                        CreateName = request.CreateName,
                        CreateTime = time
                    };
                    await _report_record.AddAsync(reportRecord);

                    // 4. 创建报工审核记录（Report_approval）
                    var reportApproval = new Report_approval
                    {
                        Report_id = productionReport.Id,
                        Approval_id = 1, // 这里需要根据实际业务设置审核人员ID
                        Approval_status = 1, // 1待审批
                        Approval_date = time,
                        Comments = "",
                        CreateName = request.CreateName,
                        CreateTime = time
                    };
                    // 新增：自动生成 //报工审核记录
                    if (string.IsNullOrEmpty(reportApproval.ReportNo))
                    {
                        var generatedCode = await codeRuleService.AutoGenerateCodeAsync("ProduceBasicData.Domain.ProductionManage.Report_approval");
                        if (!string.IsNullOrEmpty(generatedCode))
                        {
                            reportApproval.ReportNo = generatedCode;
                        }
                        else
                        {
                            // 如果没有配置规则，使用默认生成方式
                            reportApproval.ReportNo = $"WO{DateTime.Now:yyyyMMddHHmmss}";
                        }
                    }
                    await _report_approval.AddAsync(reportApproval);

                    // 提交事务
                    await transaction.CommitAsync(cancellationToken);
                    result.Data = productionReport.Id;

                    // 发送实时通知
                    try
                    {
                        var notificationMessage = $"报工单{productionReport.Report_no}已提交，请及时处理";
                        var notificationResult = await _notificationService.SendProductionReportSubmitNotificationAsync(
                            productionReport.Report_no,
                            notificationMessage
                        );

                        if (notificationResult.Code == ApiEnum.Success)
                        {
                            _logger.LogInformation($"报工单{productionReport.Report_no}提交通知已发送");
                        }
                        else
                        {
                            _logger.LogWarning($"报工单{productionReport.Report_no}提交通知发送失败: {notificationResult.Msg}");
                        }
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError(ex, $"发送报工单{productionReport.Report_no}提交通知失败");
                    }
                }
            }
            catch (Exception ex)
            {
                result.Code = ApiEnum.Failed;
                result.Msg = $"下发报工失败：{ex.Message}";
            }

            return result;
        }
    }
}
